package com.dcm.live.service.impl;

import com.dcm.common.constant.LiveConstant;
import com.dcm.common.enums.LikeStatusEnum;
import com.dcm.common.exception.MyException;
import com.dcm.common.service.RedisService;
import com.dcm.common.utils.RedisKeyUtils;
import com.dcm.live.dto.LikedCountDto;
import com.dcm.live.entity.LiveRoomEntity;
import com.dcm.live.entity.UserFocusEntity;
import com.dcm.live.entity.UserLikeEntity;
import com.dcm.live.mapper.FocusMapper;
import com.dcm.live.service.FocusService;
import com.dcm.live.service.LiveRoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * [关注功能]
 *
 * @author : [pengrongsheng]
 * @createTime : [2021/4/9]
 */
@Service
public class FocusServiceImpl implements FocusService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private LiveRoomService roomService;

    @Autowired
    private FocusMapper focusMapper;

    @Override
    public void transFromRedis2db() {
        List<UserFocusEntity> list = getFocusDataFromRedis();
        for (UserFocusEntity focus : list) {
            UserFocusEntity uf = focusMapper.findByUidAndId(focus.getFocusUserId(), focus.getFocusPostId());

            if (uf == null) {
                focusMapper.insert(focus);
            } else {
                uf.setStatus(focus.getStatus());
                focusMapper.update(focus);
            }
        }
    }

    @Override
    public void transFocusCountFromRedis2db() {
        List<LikedCountDto> list = getFocusCountFromRedis();
        for (LikedCountDto count : list) {
            LiveRoomEntity room = roomService.findRoomByUserId(count.getLikedUserId());
            if (room != null) {
                Integer focusNum = room.getFocusNum() + count.getCount();
                room.setFocusNum(focusNum);
                roomService.updateRoom(room);
            }
        }
    }

    /**
     * 关注
     * @param uid 用户id
     * @param id 主播的用户id
     */
    @Override
    public void saveFocus2Redis(Long uid, Long id) {
        redisService.hSet(LiveConstant.MAP_KEY_USER_FOCUS, RedisKeyUtils.getLikedKey(uid,id), LikeStatusEnum.FOCUS.getCode());
        incrementCount(uid);
    }

    /**
     * 取消关注
     * @param uid 用户id
     * @param id 主播的用户id
     */
    @Override
    public void blurFromRedis(Long uid, Long id) {
        redisService.hSet(LiveConstant.MAP_KEY_USER_FOCUS, RedisKeyUtils.getLikedKey(uid,id), LikeStatusEnum.BLUR.getCode());
        decrementCount(uid);
    }

    /**
     * 递增
     * @param uid
     */
    @Override
    public void incrementCount(Long uid) {
        String mapKey = LiveConstant.MAP_KEY_USER_FOCUS_COUNT;
        String uidKey = uid + "";
        Object o = redisService.hGet(mapKey, uidKey);
        if (o == null) {
            redisService.hSet(mapKey, uidKey, 1L);
        } else {
            redisService.hIncr(mapKey, uidKey, 1L);
        }
    }

    @Override
    public void decrementCount(Long uid) {
        String mapKey = LiveConstant.MAP_KEY_USER_FOCUS_COUNT;
        String uidKey = uid + "";
        Object o = redisService.hGet(mapKey, uidKey);
        if (o == null) {
            throw new MyException("无此用户！");
        } else {
            redisService.hIncr(mapKey, uidKey, -1L);
        }
    }

    @Override
    public List<UserFocusEntity> getFocusDataFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisService.hScan(LiveConstant.MAP_KEY_USER_FOCUS);
        ArrayList<UserFocusEntity> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Map.Entry<Object, Object> entry = cursor.next();
            String key = (String) entry.getKey();
            //分离出 likedUserId，likedPostId
            String[] split = key.split("::");
            Long likedUserId = Long.parseLong(split[0]);
            Long likedPostId = Long.parseLong(split[1]);
            Integer value = (Integer) entry.getValue();
            //组成 UserLikeEntity 对象 存入 list
            UserFocusEntity focusEntity = new UserFocusEntity(likedUserId, likedPostId, value);
            list.add(focusEntity);

            redisService.hDel(LiveConstant.MAP_KEY_USER_FOCUS, key);
        }
        return list;
    }

    @Override
    public List<LikedCountDto> getFocusCountFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisService.hScan(LiveConstant.MAP_KEY_USER_FOCUS_COUNT);
        List<LikedCountDto> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Map.Entry<Object, Object> map = cursor.next();
            //将点赞数量存储在 LikedCountDto
            String key = (String) map.getKey();
            Long id = Long.parseLong(key);
            LikedCountDto dto = new LikedCountDto(id, (Integer) map.getValue());
            list.add(dto);
            //从Redis中删除这条记录
            redisService.hDel(LiveConstant.MAP_KEY_USER_FOCUS_COUNT, key);
        }
        return list;
    }
}
